package com.youlai.quarkus.system.common.redis;

import com.alibaba.fastjson2.JSON;
import com.youlai.quarkus.system.common.util.FastJson2Util;
import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.keys.KeyCommands;
import io.quarkus.redis.datasource.value.SetArgs;
import io.quarkus.redis.datasource.value.ValueCommands;
import jakarta.enterprise.context.ApplicationScoped;

import java.lang.reflect.Type;

/**
 * Redis service 实现
 *
 * @author csp 2023-10-29
 */
@ApplicationScoped
public class RedisServiceImpl implements IRedisService{

    private final ValueCommands<String, String> commands;
    private final KeyCommands<String> keyCommands;


    public RedisServiceImpl(RedisDataSource redisApi) {
        commands = redisApi.value(String.class);
        keyCommands = redisApi.key(String.class);
    }

    @Override
    public void set(String key, Object val, long timeout) {
        SetArgs args = new SetArgs();
        args.ex(timeout);
        String newVal = val.getClass().isAssignableFrom(String.class) ? val.toString() : JSON.toJSONString(val);
        commands.set(key, newVal, args);
    }

    @Override
    public void set(String key, Object val) {
        String newVal = val.getClass().isAssignableFrom(String.class) ? val.toString() : JSON.toJSONString(val);
        commands.set(key, newVal);
    }

    @Override
    public <T> T get(String key, Class<T> clazz) {
        String value = this.commands.get(key);
        return String.class.isAssignableFrom(clazz) ? (T) value : JSON.parseObject(value, FastJson2Util.buildType(new Type[]{clazz}));
    }

    @Override
    public boolean tryLock(String key, long exp) {
        boolean setnx = this.commands.setnx(key, "1");
        if (setnx) {
            keyCommands.expire(key, exp);
        }
        return setnx;
    }
}
